const forge = require('node-forge')
const fs = require('fs')

const createSelfSignedCert = () => {
  // 生成RSA密钥对，密钥长度为2048位
  const keys = forge.pki.rsa.generateKeyPair(2048)

  // 创建一个新的X.509证书
  const cert = forge.pki.createCertificate()
  // 将公钥设置为生成的公钥
  cert.publicKey = keys.publicKey
  // 设置证书的序列号
  cert.serialNumber = '01'

  // 设置证书的有效期，从当前时间开始，有效期为1年
  cert.validity.notBefore = new Date()
  cert.validity.notAfter = new Date()
  cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1)

  // 定义证书的主题属性，包括通用名称、国家名称、州/省名称、地区名称、组织名称等
  const attrs = [
    { name: 'commonName', value: 'localhost' },
    { name: 'countryName', value: 'US' },
    { shortName: 'ST', value: 'California' },
    { name: 'localityName', value: 'San Francisco' },
    { name: 'organizationName', value: 'My Company' },
    { shortName: 'OU', value: 'My Company' }
  ]

  // 设置证书的主题和颁发者属性
  cert.setSubject(attrs)
  cert.setIssuer(attrs)

  // 设置证书的扩展属性，如基本约束、密钥用途、扩展密钥用途等
  cert.setExtensions([
    {
      name: 'basicConstraints',
      cA: true
    },
    {
      name: 'keyUsage',
      keyCertSign: true,
      digitalSignature: true,
      nonRepudiation: true,
      keyEncipherment: true,
      dataEncipherment: true
    },
    {
      name: 'extKeyUsage',
      serverAuth: true,
      clientAuth: true,
      codeSigning: true,
      emailProtection: true,
      timeStamping: true
    },
    {
      name: 'nsCertType',
      client: true,
      server: true,
      email: true,
      objsign: true,
      sslCA: true,
      emailCA: true,
      objCA: true
    }
  ])

  // 使用生成的私钥自签名证书
  cert.sign(keys.privateKey)

  // 将生成的私钥和证书转换为PEM格式
  const pem = {
    privateKey: forge.pki.privateKeyToPem(keys.privateKey),
    certificate: forge.pki.certificateToPem(cert)
  }

  // 返回PEM格式的私钥和证书
  return pem
}

// 将PEM格式的私钥和证书写入本地文件
const savePemFiles = (privateKey, certificate) => {
  fs.writeFileSync('data/privateKey.pem', privateKey)
  fs.writeFileSync('data/certificate.pem', certificate)
}

const { privateKey, certificate } = createSelfSignedCert()
savePemFiles(privateKey, certificate)